"""
# \如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后，短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
#
# 字母和数字都属于字母数字字符。
#
# 给你一个字符串 s，如果它是 回文串 ，返回 true ；否则，返回 false 。
#
#
#
# 示例 1：
#
# 输入: s = "A man, a plan, a canal: Panama"
# 输出：true
# 解释："amanaplanacanalpanama" 是回文串。
# 示例 2：
#
# 输入：s = "race a car"
# 输出：false
# 解释："raceacar" 不是回文串。
# 示例 3：
#
# 输入：s = " "
# 输出：true
# 解释：在移除非字母数字字符之后，s 是一个空字符串 "" 。
# 由于空字符串正着反着读都一样，所以是回文串。
#
#
# 提示：
#
# 1 <= s.length <= 2 * 105
# s 仅由可打印的 ASCII 字符组成
"""

class Solution(object):
    def isPalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        1. 分别定义从左和从右开始的指针
        2. 循环一个一个字符的往中间对比，如果遇到不同，直接终止;
        """
        #  定义双指针
        left, right = 0, len(s) - 1
        while left < right:
            # 判断是否只包含数字和字母
            while left < right and not s[left].isalnum():
                left += 1
            while left < right and not s[right].isalnum():
                right -= 1
            if s[left].lower() != s[right].lower():
                return False
            left += 1
            right -= 1
        return True





# 开始测试
soultion = Solution()

# 定义一些测试用例
test_cases = [
    ("A man, a plan, a canal: Panama", True),  # 经典回文
    ("race a car", False),  # 不是回文
    ("", True),  # 空字符串是回文
    ("Madam", True),  # 忽略大小写
    ("No 'x' in Nixon", True),  # 包含标点和空格
    ("Was it a car or a cat I saw?", True),  # 复杂回文
    ("hello", False),  # 普通非回文
    ("12321", True),  # 数字回文
    ("12345", False),  # 非回文数字
    ("0P", True),  # 大小写混合，不匹配
]

# 逐个测试
for s, expected in test_cases:
    result = soultion.isPalindrome(s)
    # 值1 if 条件 else 值2
    status = "✅ 通过" if result == expected else "❌ 失败"
    print(f"输入: '{s}' | 期望: {expected} | 实际: {result} | {status}")
